home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / wais / ui / source.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  20KB  |  833 lines

  1. /* 
  2.   WIDE AREA INFORMATION SERVER SOFTWARE:
  3.    No guarantees or restrictions.  See the readme file for the full standard
  4.    disclaimer.
  5.  
  6.    This is part of the shell user-interface tools for the WAIS software.
  7.    Do with it as you please.
  8.  
  9.    jonathan@Think.COM
  10.  *
  11.  * $Log: source.c,v $
  12.  * Revision 5.1  1992/07/10  23:13:28  curtisg
  13.  * Distributed version
  14.  *
  15.  * Revision 1.16  92/04/02  14:22:23  jonathan
  16.  * Added sopysourceID.
  17.  * 
  18.  * Revision 1.15  92/04/01  17:18:39  jonathan
  19.  * Added FORWARDER_SERVER stuff.
  20.  * 
  21.  * Revision 1.14  92/03/17  14:39:55  jonathan
  22.  * Cleaned up.
  23.  * 
  24.  * Revision 1.13  92/03/06  14:50:53  jonathan
  25.  * New and Improved source loading!
  26.  * 
  27.  * Revision 1.12  92/03/05  11:47:30  jonathan
  28.  * Replaced directory routines with scandir's.
  29.  * 
  30.  * Revision 1.11  92/03/04  19:21:11  jonathan
  31.  * Handle EOF on read of source.  This fixes looping when source description
  32.  * is broken.
  33.  * 
  34.  * Revision 1.10  92/03/04  18:45:17  jonathan
  35.  * Modified WriteSource to use WriteString for description.
  36.  * 
  37.  * Revision 1.9  92/03/01  13:53:30  jonathan
  38.  * Added routines for X interface in effort to combine x/source.c and
  39.  * ui/source.c
  40.  * 
  41.  * Revision 1.8  92/03/01  13:07:25  jonathan
  42.  * Added check of s->thisSource to avoid errors when there are no sources.
  43.  * 
  44.  */
  45.  
  46. #ifndef lint
  47. static char *RCSid = "$Header: /y/src/wais/wais-8-b5/ui/RCS/source.c,v 5.1 1992/07/10 23:13:28 curtisg Exp curtisg $";
  48. #endif
  49.  
  50. #define _C_SOURCE
  51.  
  52. #include "wais.h"
  53. #include "globals.h"
  54.  
  55. #define DESC_SIZE 65535
  56.  
  57. extern int alphasort();
  58.  
  59. void
  60. freeSourceID(sid)
  61. SourceID sid;
  62. {
  63.   if (sid != NULL) {
  64.     if (sid->filename != NULL) s_free(sid->filename);
  65.     s_free(sid);
  66.   }
  67. }
  68.  
  69. SourceID
  70. copysourceID(sid)
  71. SourceID sid;
  72. {
  73.   SourceID result = NULL;
  74.   if(sid != NULL) {
  75.     if((result = (SourceID) s_malloc(sizeof(_SourceID))) != NULL) {
  76.       result->filename = s_strdup(sid->filename);
  77.     }
  78.   }
  79.   return result;
  80. }
  81.  
  82. char **
  83. buildSourceItemList(sourcelist)
  84. SourceList sourcelist;
  85. {
  86.   char **result;
  87.   int num, i;
  88.   SourceList source;
  89.  
  90.   /* find the length of the sidlist in the question */
  91.  
  92.   for(num = 0, source = sourcelist; 
  93.       source != NULL && source->thisSource != NULL;
  94.       num++, source = source->nextSource);
  95.  
  96.   result = (char**)s_malloc(1+num*sizeof(char*));
  97.   if(num > 0)
  98.     for(i =0, source = sourcelist; i<num; i++, source = source->nextSource)
  99.       result[i] = source->thisSource->filename;
  100.   result[num] = NULL;
  101.   return(result);
  102. }
  103.  
  104. char **
  105. buildSItemList(sourcelist)
  106. SList sourcelist;
  107. {
  108.   char **result;
  109.   int num, i;
  110.   SList source;
  111.  
  112.   /* find the length of the sidlist in the question */
  113.  
  114.   for(num = 0, source = sourcelist; 
  115.       source != NULL;
  116.       num++, source = source->nextSource);
  117.  
  118.   result = (char**) s_malloc(1+num*sizeof(char*));
  119.   if(num > 0)
  120.     for(i =0, source = sourcelist; i<num; i++, source = source->nextSource)
  121.       if(source->thisSource != NULL)
  122.     result[i] = source->thisSource->name;
  123.   result[num] = NULL;
  124.   return(result);
  125. }
  126.  
  127. short
  128. ReadSourceID(file, sid)
  129. FILE *file;
  130. SourceID sid;
  131. {
  132.   char temp_string[MAX_SYMBOL_SIZE];
  133.   char filename[MAX_SYMBOL_SIZE];
  134.   short check_result;
  135.  
  136.   check_result = CheckStartOfStruct("source-id", file);
  137.   filename[0] = '\0';
  138.   if(FALSE == check_result){ 
  139.     return(false);
  140.   }
  141.   if(END_OF_STRUCT_OR_LIST == check_result)
  142.     {
  143.       return(FALSE);
  144.     }
  145.     
  146.   /* read the slots: */
  147.   while(TRUE){
  148.  
  149.     short check_result = ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE);
  150.     if(END_OF_STRUCT_OR_LIST == check_result) break;
  151.     if(FALSE == check_result){
  152.       return(false);
  153.     } 
  154.     if(0 == strcmp(temp_string, ":filename")) {
  155.       if (FALSE == ReadString(filename, file, MAX_SYMBOL_SIZE))
  156.     return(false);
  157.       sid->filename = s_strdup(filename);
  158.     }
  159.     else
  160.       SkipObject(file);
  161.   }
  162.   return(TRUE);
  163. }
  164.  
  165. SourceList ReadListOfSources(file)
  166. FILE *file;
  167. {
  168.   short check_result;
  169.   SourceID sid = NULL;
  170.   SourceList result, this, last;
  171.           
  172.   /* initialize */
  173.   this = last = result = NULL;
  174.  
  175.   if(ReadStartOfList(file) == FALSE)
  176.     return(NULL);
  177.  
  178.   while(TRUE) {
  179.     sid = (SourceID)s_malloc(sizeof(_SourceID));
  180.     check_result = ReadSourceID(file, sid);
  181.     if(check_result == END_OF_STRUCT_OR_LIST) {
  182.       s_free(sid);
  183.       return(result);
  184.     }
  185.     else if(check_result == FALSE)
  186.       return(result);
  187.  
  188.     else if(check_result == TRUE) {
  189.       if(result == NULL)
  190.     result = this = (SourceList)s_malloc(sizeof(_SourceList));
  191.       else
  192.     this = (SourceList)s_malloc(sizeof(_SourceList));
  193.       this->thisSource = sid;
  194.       if(last != NULL)
  195.     last->nextSource = this;
  196.       last = this;
  197.     }
  198.   }
  199. }
  200.  
  201. Boolean ReadSource(source, file)
  202. Source source;
  203. FILE *file;
  204. {
  205.   char temp_string[MAX_SYMBOL_SIZE];
  206.   char desc_string[DESC_SIZE];
  207.   short check_result;
  208.   long port;
  209.  
  210.   long version;
  211.  
  212.   /* make sure it's a Source */
  213.   
  214.   check_result = CheckStartOfStruct("source", file);
  215.   if(FALSE == check_result){ 
  216.     return(false);
  217.   }
  218.   if(END_OF_STRUCT_OR_LIST == check_result)
  219.     {
  220.       return(FALSE);
  221.     }
  222.     
  223.   strcpy(source->server, "");
  224.   strcpy(source->service, "");
  225.  
  226.   /* read the slots: */
  227.   while(TRUE){
  228.  
  229.     short check_result = ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE);
  230.     if((END_OF_STRUCT_OR_LIST == check_result)  || 
  231.        (EOF == check_result))
  232.       break;
  233.     if(FALSE == check_result){
  234.       return(false);
  235.     } 
  236.     if(0 == strcmp(temp_string, ":version")) {
  237.       if(FALSE == ReadLong(file, &version))
  238.     return(false);
  239.     }
  240.     else if(0 == strcmp(temp_string, ":ip-name")) {
  241.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  242.     return(false);
  243.       strcpy(source->server, temp_string);
  244.     }
  245.     else if(0 == strcmp(temp_string, ":ip-address")) {
  246.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  247.     return(false);
  248.       strcpy(source->server, temp_string);
  249.     }
  250.     else if(0 == strcmp(temp_string, ":configuration")) {
  251.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  252.     return(false);
  253.       find_value(temp_string, "IPAddress", source->server, STRINGSIZE);
  254.       find_value(temp_string, "RemotePort", source->service, STRINGSIZE);
  255.     }
  256.     else if(0 == strcmp(temp_string, ":tcp-port")) {
  257.       if(FALSE == ReadLong(file, &port))
  258.     return(false);
  259.       sprintf(source->service,"%d", port);
  260.     }
  261.     else if(0 == strcmp(temp_string, ":port")) {
  262.       if(FALSE == ReadLong(file, &port))
  263.     return(false);
  264.       sprintf(source->service,"%d", port);
  265.     }
  266.     else if(0 == strcmp(temp_string, ":maintainer")) {
  267.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  268.     return(false);
  269.       if(source->maintainer != NULL) s_free(source->maintainer);
  270.       source->maintainer = s_strdup(temp_string);
  271.     }
  272.     else if(0 == strcmp(temp_string, ":database-name")) {
  273.       if(FALSE == ReadString(temp_string, file, MAX_SYMBOL_SIZE))
  274.     return(false);
  275.       strcpy(source->database, temp_string);
  276.     }
  277.     else if(0 == strcmp(temp_string, ":cost")) {
  278.       double cost;
  279.       if(FALSE == ReadDouble(file, &cost))
  280.     return(false);
  281.       sprintf(source->cost, "%.2f", cost);
  282.     }
  283.     else if(0 == strcmp(temp_string, ":cost-unit")) {
  284.       if(FALSE == ReadSymbol(temp_string, file, MAX_SYMBOL_SIZE))
  285.     return(false);
  286.       strcpy(source->units, temp_string);
  287.     }
  288.     else if(0 == strcmp(temp_string, ":description")) {
  289.       if(FALSE == ReadString(desc_string, file, DESC_SIZE))
  290.     return(false);
  291.       if(source->description != NULL) s_free(source->description);
  292.       source->description = s_strdup(desc_string);
  293.     }
  294.     else if(0 == strcmp(temp_string, ":update-time")) {
  295.       if(EOF == SkipObject(file)) break;
  296.     }
  297.     else
  298.       if(EOF == SkipObject(file)) break; /* we don't know the key, so we don't know how
  299.                to interpret the value, skip it */
  300.   }
  301.  
  302.   return(TRUE);
  303. }
  304.  
  305. Boolean ReadSourceFile(asource, filename, directory)
  306. Source asource;
  307. char *filename, *directory;
  308. {
  309.   FILE *fp;
  310.   char pathname[MAX_FILENAME_LEN+1];
  311.   Boolean result;
  312.  
  313.   strncpy(pathname, directory, MAX_FILENAME_LEN);
  314.   strncat(pathname, filename, MAX_FILENAME_LEN);
  315.  
  316.   if((fp = fopen(pathname, "r")) == NULL)
  317.     return FALSE;
  318.  
  319.   asource->name = s_strdup(filename);
  320.   asource->directory = s_strdup(directory);
  321.  
  322.   result = ReadSource(asource, fp);
  323.   fclose(fp);
  324.   return(result);
  325. }
  326.  
  327. Source
  328. loadSource(name)
  329. char *name;
  330. {
  331.   char *i, *p, source_dir[MAX_FILENAME_LEN], sp[1000];
  332.   Source source = (Source)s_malloc(sizeof(_Source));
  333.  
  334.   if((sourcepath = getenv("WAISSOURCEPATH")) == NULL) {
  335.     sprintf(sp,"%s:%s", sdir, cdir);
  336.     sourcepath = sp;
  337.   }
  338.  
  339.   for (p = sourcepath, i = strchr(p, ':');
  340.        i != NULL;
  341.        p = i+1) {
  342.     if((i = strchr(p, ':')) == NULL)
  343.       strcpy(source_dir, p);
  344.     else {
  345.       strncpy(source_dir, p, i-p);
  346.       source_dir[i-p] = 0;
  347.     }
  348.  
  349.     if(ReadSourceFile(source, name, source_dir)) {
  350.       set_connection(source);
  351.       Sources = makeSList(source, Sources);
  352.       return (source);
  353.     }
  354.   }
  355.   s_free(source);
  356.   source = NULL;
  357.   return (source);
  358. }
  359.  
  360. void set_connection(source)
  361. Source source;
  362. {
  363.   SList s;
  364.   for(s = Sources; s != NULL; s = s->nextSource) {
  365.     if(s->thisSource != NULL)
  366.       if (!strcmp(source->server, s->thisSource->server) &&
  367.       !strcmp(source->service, s->thisSource->service)) {
  368.     source->connection = s->thisSource->connection;
  369.     source->buffer_length = s->thisSource->buffer_length;
  370.     source->initp = s->thisSource->initp;
  371.     break;
  372.       }
  373.   }
  374. }
  375.  
  376. Boolean newSourcep(name)
  377. char *name;
  378. {
  379.   SList s;
  380.  
  381.   for (s = Sources; s != NULL; s = s->nextSource)
  382.     if((s->thisSource != NULL) &&
  383.        !strcmp(name, s->thisSource->name))
  384.       return FALSE;
  385.  
  386.   return TRUE;
  387. }
  388.  
  389. Boolean is_source(name, test)
  390. char *name;
  391. Boolean test;
  392. {
  393.   char lastchar;
  394.  
  395.   lastchar = name[strlen(name)-1];
  396.   if(test) 
  397.     return ((strlen(name) > 4) &&
  398.       strstr(name, ".src") &&
  399.       (!strcmp(".src", strstr(name, ".src"))));
  400.   else 
  401.     return (lastchar != '~' &&
  402.         lastchar != '#' &&
  403.         strcmp(name, ".") &&
  404.         strcmp(name, ".."));
  405. }
  406.  
  407. static Boolean newSource(name)
  408. char *name;
  409. {
  410.   int i;
  411.  
  412.   for(i =0; i < NumSources; i++)
  413.     if(!strcmp(name, Source_items[i]))
  414.       return FALSE;
  415.  
  416.   return TRUE;
  417. }
  418.  
  419. static int
  420. issfile(dp)
  421. struct dirent *dp;
  422. {
  423.   return(is_source(dp->d_name, TRUE) &&
  424.      newSource(dp->d_name));
  425. }
  426.  
  427. void SortSourceNames(n)
  428. int n;
  429. {
  430.   Boolean Changed = TRUE;
  431.   int i;
  432.   char *qi;
  433.  
  434.   while(Changed) {
  435.     Changed = FALSE;
  436.     for(i = 0; i < n-1; i++)
  437.       if(0 < strcasecmp(Source_items[i], Source_items[i+1])) {
  438.     Changed = TRUE;
  439.     qi = Source_items[i];
  440.     Source_items[i] = Source_items[i+1];
  441.     Source_items[i+1] = qi;
  442.       }
  443.   }
  444. }
  445.  
  446. void
  447. GetSourceNames(directory)
  448. char *directory;
  449. {
  450.   struct dirent **list;
  451.   int i, j;
  452.  
  453.   if ((j = scandir(directory, &list, issfile, alphasort)) < 0) {
  454.       char booboo[STRINGSIZE];
  455.       sprintf(booboo, "Error on open of source directory: %s.\n", directory);
  456.       PrintStatus(booboo);
  457.       return;
  458.     }
  459.  
  460.   if(NumSources > 0)
  461.     Source_items = (char**) s_realloc(Source_items, (NumSources+j+1) * sizeof(char*));
  462.   else {
  463.     if(Source_items != NULL) {
  464.       for (i = 0; Source_items[i] != NULL; i++) s_free(Source_items[i]);
  465.       s_free(Source_items);
  466.     }
  467.     Source_items = (char**) s_malloc((j+1) * sizeof(char*));
  468.   }
  469.  
  470.   for (i = 0; i < j; i++) {
  471.     Source_items[i+NumSources] = s_strdup(list[i]->d_name);
  472.     s_free(list[i]);
  473.   }
  474.  
  475.   NumSources+=j;
  476.   SortSourceNames(NumSources);
  477.   Source_items[NumSources] = NULL;
  478.  
  479.   s_free(list);
  480. }
  481.  
  482. /* read all the sources from a directory.  If test is true, only files ending
  483.    in .src are valid
  484.    */
  485.  
  486. void
  487. ReadSourceDirectory(directory, test)
  488. char *directory;
  489. Boolean test;
  490. {
  491.   char filename[MAX_FILENAME_LEN];
  492.   FILE *fp;
  493.   int i, j , newNumSources;
  494.   SList Last;
  495.   Source source;
  496.   struct dirent **list;
  497.  
  498.   if ((j = scandir(directory, &list, NULL, NULL)) < 0) {
  499.     return;
  500.   }
  501.  
  502.   /* find the end of the sourcelist */
  503.   if(Sources == NULL)
  504.     Sources = makeSList(NULL, NULL);
  505.  
  506.   for(Last = Sources; Last->nextSource != NULL; Last = Last->nextSource);
  507.  
  508.   for (i = 0; i < j; i++) {
  509.     if (is_source(list[i]->d_name, test)) {
  510.       if(newSourcep(list[i]->d_name)) {
  511.     strcpy(filename, directory);
  512.     strcat(filename, list[i]->d_name);
  513.     if ((fp = fopen(filename, "r")) != NULL) {
  514.       source = (Source)s_malloc(sizeof(_Source));
  515.       memset(source, 0, sizeof(_Source));
  516.       source->initp = FALSE;
  517.       source->name = s_strdup(list[i]->d_name);
  518.       source->directory = s_strdup(directory);
  519.       ReadSource(source, fp);
  520.       fclose(fp);
  521.       if(Last->thisSource == NULL)
  522.         Last->thisSource = source;
  523.       else {
  524.         Last->nextSource = makeSList(source, NULL);
  525.         Last = Last->nextSource;
  526.       }
  527.       NumSources++;
  528.     }
  529.       }
  530.     }
  531.   }
  532.   free((char *)list);
  533. }
  534.  
  535. void WriteSource(directory, source, overwrite)
  536.      char *directory;
  537.      Source source;
  538.      Boolean overwrite;
  539. {
  540.   char filename[MAX_FILENAME_LEN];
  541.   FILE *fp;
  542.   
  543.   /* build filename */
  544.   
  545.   strcpy(filename, directory);
  546.   strcat(filename, source->name);
  547.   
  548.   /* test to see if it exists */
  549.   
  550.   if (overwrite == FALSE) 
  551.     if ((fp = fopen(filename, "r")) != NULL) {
  552.       char outstring[STRINGSIZE];
  553.       sprintf(outstring, "File %s exists, click again to overwrite.\n", filename);
  554.       PrintStatus(outstring);
  555.       fclose(fp);
  556.       return;
  557.     }
  558.   
  559.   if ((fp = fopen(filename, "w")) == NULL) {
  560.     char outstring[STRINGSIZE];
  561.     sprintf(outstring, "Error opening %s.\n", filename);
  562.     PrintStatus(outstring);
  563.     return;
  564.   }
  565.   
  566.   fprintf(fp, "(:source\n :version 3\n");
  567.   if(source->server != NULL) 
  568.     if(source->server[0] != 0)
  569.       if(isdigit(source->server[0])) /* then it's an ip-address */
  570.     fprintf(fp, " :ip-address \"%s\"\n", source->server);
  571.       else
  572.     fprintf(fp, " :ip-name \"%s\"\n", source->server);
  573.  
  574.   if(source->service != NULL) 
  575.     if(source->service[0] != 0)
  576.       fprintf(fp, " :tcp-port %s\n", source->service);
  577.  
  578.   fprintf(fp, " :database-name \"%s\"\n", source->database);
  579.   if(source->cost != NULL) 
  580.     if(source->cost[0] != 0)
  581.       fprintf(fp, " :cost %s \n", source->cost);
  582.   else
  583.       fprintf(fp, " :cost 0.00 \n");
  584.  
  585.   if(source->units != NULL) 
  586.     if(source->units[0] != 0)
  587.       fprintf(fp, " :cost-unit %s \n", source->units);
  588.   else
  589.     fprintf(fp, " :cost-unit :free \n");
  590.   
  591.   if(source->maintainer != NULL) 
  592.     if(source->maintainer[0] != 0)
  593.       fprintf(fp, " :maintainer \"%s\"\n", 
  594.           source->maintainer);
  595.   else
  596.       fprintf(fp, " :maintainer \"%s\"\n", 
  597.           current_user_name());
  598.  
  599.   if(source->description != NULL) 
  600.     if(source->description[0] != 0) {
  601.       fprintf(fp, " :description ");
  602.       WriteString(source->description, fp);
  603.     }
  604.   else
  605.     fprintf(fp, " :description \"Created with %s by %s on %s.\"\n",
  606.         command_name, current_user_name(), printable_time());
  607.  
  608.   fprintf(fp, "\n)");
  609.   fclose(fp);
  610. }
  611.  
  612. SourceList
  613.   makeSourceList(source, rest)
  614. SourceID source;
  615. SourceList rest;
  616. {
  617.   SourceList result;
  618.   if((result = (SourceList)s_malloc(sizeof(_SourceList))) != NULL) {
  619.     result->thisSource = source;
  620.     result->nextSource = rest;
  621.   }
  622.   return(result);
  623. }
  624.  
  625. SList
  626.   makeSList(source, rest)
  627. Source source;
  628. SList rest;
  629. {
  630.   SList result;
  631.   if((result = (SList)s_malloc(sizeof(_SList))) != NULL) {
  632.     result->thisSource = source;
  633.     result->nextSource = rest;
  634.   }
  635.   return(result);
  636. }
  637.  
  638. void FreeSource(source)
  639. Source source;
  640. {
  641.   if (source != NULL) {
  642.     if(source->name != NULL)
  643.       s_free (source->name);
  644.     if(source->directory != NULL)
  645.       s_free (source->directory);
  646.     if(source->description != NULL)
  647.       s_free (source->description);
  648.     if(source->maintainer != NULL)
  649.       s_free (source->maintainer);
  650.     s_free(source);
  651.   }
  652. }
  653.  
  654. void FreeSources(sources)
  655. SList sources;
  656. {
  657.  SList s, n;
  658.  
  659.  for (s = sources; s != NULL; s = n) {
  660.    n = s->nextSource;
  661.    FreeSource(s->thisSource);
  662.    s_free(s);
  663.  }
  664.  
  665.  NumSources = 0;
  666.  sources = NULL;
  667. }
  668.  
  669. Source
  670.   findsource(name)
  671. char *name;
  672. {
  673.   SList asource;
  674.  
  675.   for(asource = Sources; 
  676.       asource != NULL;
  677.       asource = asource->nextSource) {
  678.     if (!strcmp(name, asource->thisSource->name)) {
  679.       return asource->thisSource;
  680.     }
  681.   }
  682.   return (loadSource(name));
  683. }
  684.  
  685. Source
  686.   findSource(n)
  687. int n;
  688. {
  689.   SList asource;
  690.  
  691.   for(asource = Sources; 
  692.       (n > 0) && (asource != NULL);
  693.       asource = asource->nextSource, n--);
  694.  
  695.   if (asource != NULL) return asource->thisSource;
  696.   else return NULL;
  697. }
  698.  
  699. void
  700. format_source_cost(str,source)
  701. char *str;
  702. Source source;
  703. {
  704.   sprintf(str,"Free");
  705.   if ((source->units != NULL) && (source->cost != NULL)) {
  706.      
  707.      if(0 == strcmp(source->units, ":dollars-per-query"))
  708.         sprintf(str,"$%s/query",source->cost);
  709.  
  710.      if(0 == strcmp(source->units, ":dollars-per-minute"))
  711.         sprintf(str,"$%s/minute",source->cost);
  712.  
  713.      if(0 == strcmp(source->units, ":dollars-per-retrieval"))
  714.         sprintf(str,"$%s/retrieval",source->cost);
  715.  
  716.      if(0 == strcmp(source->units, ":dollars-per-session"))
  717.         sprintf(str,"$%s/session",source->cost);
  718.  
  719.      if(0 == strcmp(source->units, ":other"))
  720.         sprintf(str,"Special",source->cost);
  721.   }
  722. }
  723.  
  724. void
  725. freeSourceList(slist)
  726. SourceList slist;
  727. {
  728.   SourceList sl;
  729.   while(slist != NULL) {
  730.     sl = slist;
  731.     freeSourceID(sl->thisSource);
  732.     slist = sl->nextSource;
  733.     s_free(sl);
  734.   }
  735. }
  736.  
  737. #include <sockets.h>
  738.  
  739. Boolean init_for_source(source, request, length, response)
  740. Source source;
  741. char *request;
  742. long length;
  743. char *response;
  744. /* send an init message to the source.  A side effect is that the 
  745.    negotiation of buffer sizes.  The final size is put in 
  746.    source->buffer_length 
  747.  */
  748. {
  749.   char userInfo[500];
  750.   char message[500];
  751.   char hostname[80];
  752.   char domain[80];
  753.  
  754.   gethostname(hostname, 80);
  755. #ifdef M_UNIX
  756.   domain[0] = '\0';
  757. #else
  758.   getdomainname(domain, 80);
  759. #endif
  760.  
  761. #ifdef TELL_USER
  762.   sprintf(userInfo, "%s %s, from host: %s.%s, user: %s",
  763.       command_name, VERSION, hostname, domain, getenv("USER"));
  764. #else
  765.   sprintf(userInfo, "%s %s, from host: %s.%s",
  766.       command_name, VERSION, hostname, domain);
  767. #endif
  768.  
  769.   if(source->initp == FALSE) {
  770.     if(source->server[0] == 0)
  771.       source->connection = NULL;
  772.     else {
  773.       source->connection = connect_to_server(source->server,
  774.                          atoi(source->service));
  775. #ifdef FORWARDER_SERVER
  776.  
  777. #ifndef FORWARDER_SERVICE
  778. #define FORWARDER_SERVICE "210"
  779. #endif
  780.  
  781.       if(source->connection == NULL) {
  782.     strncat(source->database, "@", STRINGSIZE);
  783.     strncat(source->database, source->server, STRINGSIZE);
  784.     strncat(source->database, ":", STRINGSIZE);
  785.     strncat(source->database, source->service, STRINGSIZE);
  786.     strncpy(source->server, FORWARDER_SERVER, STRINGSIZE);
  787.     strncpy(source->service, FORWARDER_SERVICE, STRINGSIZE);
  788.     source->connection = connect_to_server(source->server,
  789.                            atoi(source->service));
  790.       }
  791. #endif
  792.  
  793.       if (source->connection == NULL) {
  794.     PrintStatus("Bad Connection to server.\n");
  795.     source->initp = FALSE;
  796.     return source->initp;
  797.       }
  798.     }
  799.     source->buffer_length = 
  800.       init_connection(request, response,
  801.               length,
  802.               source->connection,
  803.               userInfo);
  804.  
  805.     if (source->buffer_length < 0) {
  806.       sprintf(message, "\nError connecting to server: %s service: %s.",
  807.           source->server, source->service);
  808.       PrintStatus(message);
  809.       sleep(2);
  810.       source->initp = FALSE;
  811.     }
  812.     else {
  813.       SList s;
  814.  
  815.       source->initp = TRUE;
  816.       /* set the init and connection for other sources with the same
  817.      host and port. */
  818.       for (s = Sources; s != NULL; s = s->nextSource) {
  819.           if (s->thisSource != source) {
  820.       if (strcmp(s->thisSource->server, source->server) == 0 &&
  821.           strcmp(s->thisSource->service, source->service) == 0) {
  822.         s->thisSource->connection = source->connection;
  823.         s->thisSource->buffer_length = source->buffer_length;
  824.         s->thisSource->initp = TRUE;
  825.       }
  826.     }
  827.       }
  828.     }
  829.     return source->initp;
  830.   }
  831.   return source->initp;
  832. }
  833.